package com.apes.fn.scm.retailReturn;

import com.alibaba.fastjson.JSONObject;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.todo.TodoTaskService;
import com.apes.framework.util.LogicalUtil;
import com.apes.framework.util.MapUtil;
import com.apes.pi.service.PiManager;
import com.apes.scm.account.account.service.ProductAccountService;
import com.apes.scm.account.transit.DepositInTransitService;
import com.apes.scm.masterdata.frame.model.Store;
import com.apes.scm.masterdata.frame.repository.StoreRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.masterdata.product.model.ProductUom;
import com.apes.scm.masterdata.product.repository.ProductRepository;
import com.apes.scm.masterdata.product.repository.ProductUomRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service("retailReturnNoOrderService")
public class RetailReturnNoOrderService extends DomainService {

    @Autowired
    private RetailReturnRepository retailReturnRepository;
    @Autowired
    private SequenceService sequenceService;

    /**
     * 功能: 创建
     *
     * @param request
     * @return
     */
    public RetailReturn create(SimpleRequest request) {
        RetailReturn retailReturn = request.getO(RetailReturn.class);
        JSONObject tempJson = request.getJO();
        String companyId = request.getCurrentCompany() == null ? "" : ((PartyRole)request.getCurrentCompany()).getId();
        retailReturn.setId("LV" + companyId + sequenceService.getId(RetailReturn.CONST_TABLE_NAME) );
        FnCustomerExpand customerExpand = this.invoke("fn.customerExpand.updateOrInsert", MapUtil.mapper(
                "customerExpand", tempJson.get("customerExpand"),
                "customer", tempJson.get("customerInfo"),
                "customerCar", tempJson.get("customerCar")
        ));
        retailReturn.setCustomerExpand(customerExpand);
        if (StringUtils.isEmpty(retailReturn.getCustomer())) {
            PartyRole customer = retailReturn.getCompany().getParty().getPartyRoles().stream()
                    .filter((partyRole) -> "Customer".equals(partyRole.getRole().getId())).findFirst().orElse(null);
            if (customer != null) {
                retailReturn.setCustomer(customer);
            }
        }

        return save(retailReturn);
    }

    public RetailReturn save(RetailReturn retailReturn) {
        retailReturn.computeAmt(); // 合计金额

        retailReturn.setInvoiceStatus("no");
        retailReturn.setState("sent");
        // 设置退货冲红数量为退货数量
        retailReturn.getSaleItems().forEach(saleReturnItem -> {

            if (saleReturnItem.getPriceUnit() == 0) throw new RuntimeException("退回商品价格不能为0");
            if (saleReturnItem.getPriceUnit() < 0) throw new RuntimeException("退回商品价格不能小于0");

            saleReturnItem.setQtyDelivered(saleReturnItem.getProductUomQty());
        });
        return retailReturnRepository.saveAndFlush(retailReturn);
    }

    /**
     * 检查数据
     *
     * @param request
     */
    private void checkData(SimpleRequest request) {
        String id = request.get("id");
        RetailReturn saleReturn = retailReturnRepository.findOne(id);
        if (saleReturn == null) throw new RuntimeException("订单：" + request.get("id") + " 在系统中不存在。");
        if (saleReturn.getState().equals("confirmed"))
            throw new RuntimeException("订单：" + request.get("id") + " 在系统中已审批。");
    }

    /**
     * 功能： 修改
     *
     * @param request
     * @return
     */
    public RetailReturn update(SimpleRequest request) {

        checkData(request);

        RetailReturn saleReturn = request.getO(RetailReturn.class);
        JSONObject tempJson = request.getJO();
        FnCustomerExpand customerExpand = this.invoke("fn.customerExpand.updateOrInsert", MapUtil.mapper(
                "customerExpand", tempJson.get("customerExpand"),
                "customer", tempJson.get("customerInfo"),
                "customerCar", tempJson.get("customerCar")
        ));
        saleReturn.computeAmt(); // 合计金额
        saleReturn.setCustomerExpand(customerExpand);
        // 设置退货冲红数量为退货数量
        saleReturn.getSaleItems().forEach(saleReturnItem -> saleReturnItem.setQtyDelivered(saleReturnItem.getProductUomQty()));

        return retailReturnRepository.saveAndFlush(saleReturn);
    }

    /***
     * 功能：删除
     * @param request
     * @return
     */
    public String delete(SimpleRequest request) {
        checkData(request);

        RetailReturn retailReturn = request.getO(RetailReturn.class);
        retailReturn.setDeleteDate(new Date());
        retailReturn.setDeleteUID(getPerson(request));
        retailReturn.setState("delete");
        //删除单据对应待办
        SpringManager.getBean(TodoTaskService.class).finishTask(retailReturn);
        retailReturnRepository.saveAndFlush(retailReturn);
        return "删除成功";
    }

    /***
     * 功能：审核
     * @param request
     * @return
     */
    public RetailReturn approve(SimpleRequest request) {
        checkData(request);

        RetailReturn retailReturn = request.getO(RetailReturn.class);
        retailReturn.setState("confirmed");
        retailReturn.setDateApprove(new Date());
        retailReturn.setApproveUID(getPerson(request));
        RetailReturn aReturn = retailReturnRepository.saveAndFlush(retailReturn);

        //如果无需发货直接设置退款状态
        aReturn.checkShip();
        if (aReturn.getState().equals("refund")) aReturn = retailReturnRepository.saveAndFlush(aReturn);

        /**未达帐**/
        saveDepositInTransit(aReturn);

        return aReturn;
    }

    /**
     * 未达帐
     **/
    public void saveDepositInTransit(RetailReturn retailReturn) {
        if (retailReturn.getNeedShip().equals("no")) {
            return;
        }
        DepositInTransitService depositInTransitService = SpringManager.getBean(DepositInTransitService.class);
        ProductAccountService productAccountService = SpringManager.getBean(ProductAccountService.class);
        retailReturn.getSaleItems().stream()
                .filter(orderItem -> LogicalUtil.notIn(orderItem.getProduct().getType(), "aut"))
                .forEach(item -> {
                    double occurQty = productAccountService.computeQtyUnit(retailReturn.getCompany(), item.getProduct(), item.getUom(), item.getProductUomQty());
                    depositInTransitService.save(retailReturn.getCompany(), item.getLocation(), null, retailReturn.getInnerBusinessType(), retailReturn.getInnerBusinessKey(),
                            item.getId(), item.getProduct(), occurQty, "收货");
                });
    }

    /***
     * 功能：findOne
     * @param request
     * @return
     */
    public RetailReturn findOne(SimpleRequest request) {
        Map params = MapUtil.mapper("orderType.code", "B", "id", request.get("id"));
        List<RetailReturn> list = retailReturnRepository.findAll(JpaDsl.toCriteria(params));
        if (list != null && list.size() > 0) return list.get(0);
        return null;
    }

    /**
     * 获取旧系统零售价格
     *
     * @param request
     * @return
     */
    private JSONObject getPricing(SimpleRequest request) {
        JSONObject map = request.getJO();
        Product product = SpringManager.getBean(ProductRepository.class).findOne(map.getJSONObject("product").getString("id"));
        Store store = SpringManager.getBean(StoreRepository.class).findOne(map.getString("deptId"));

        JSONObject newXS51Map = getNewXS51Map(MapUtil.mapper(
                "MDID", store.getDept().getId(),
                "PLID", product.getClassify().getId(),
                "SPID", product.getId(),
                "PPID", product.getBrand().getId(),   //品牌找品质

                "GSID", store.getCompany().getId(),
                "MDLXID", store.getStoreType().getId(),
                "CGZZID", "1007",
                "YYMS", store.getCompany().getParty().getCorporate().getOperation().getCode(),
                "SYGSID", "1007",
                "SQID", store.getBusinessCircle() == null ? null : store.getBusinessCircle().getId(),
                "XYGSID", store.getCompany().getId()
        ));

        JSONObject re1 = getXS51Price(newXS51Map);
        if (re1.getString("P001") == null) throw new RuntimeException("未找到价格文件");

        JSONObject sp = SpringManager.getBean(PiManager.class).erpFindOneData("mdmSpxxService.findOneSPxx", MapUtil.mapper("SPID", product.getId()), "商品");
        String xsdw = sp.getString("XSDW");
        ProductUom uom = new ProductUom();
        try {
            List<ProductUom> uoms = SpringManager.getBean(ProductUomRepository.class)
                    .findAll(JpaDsl.toCriteriaByEq("uomCategory.classify.id", product.getClassify().getId(), "name", xsdw));
            if (uoms.size() > 1) {
                uom = uoms.stream().filter(u -> u.getUomCategory().getId().equals(product.getId())).findFirst().orElse(uom);
            } else {
                uom = uoms.stream().findFirst().get();
            }
        } catch (Exception e) {
            throw new RuntimeException("系统中不存在该商品默认销售计量单位:" + uom.getName());
        }
        return new JSONObject(MapUtil.mapper("priceUnit", re1.getDouble("S901"), "uom", uom));
    }

    private JSONObject getXS51Price(Map map){
        Object obj = this.invoke("condition.execConditionStrategy", map);
        return new JSONObject(MapUtil.mapped(obj));
    }

    private JSONObject getNewXS51Map(Map map) {
        JSONObject result = new JSONObject();
        result.put("conditionStrategyId", "XS51");
        result.put("SYS_RQ", new Date());
        result.put("SYS_NO_CHECK", "CAR_LICENSE");

        result.put("PUR_COMPANY_ID", map.get("CGZZID") == null ? null : map.get("CGZZID"));
        result.put("PRODUCT_ID", map.get("SPID") == null ? null : map.get("SPID"));

        result.put("BRAND_ID", map.get("PPID") == null ? null : map.get("PPID"));
        result.put("QUALITY", map.get("PZID") == null ? null : map.get("PZID"));
        result.put("CLASSIFY_ID", map.get("PLID") == null ? null : map.get("PLID"));

        result.put("SAL_COMPANY_ID", map.get("XYGSID") == null ? null : map.get("XYGSID"));
        result.put("DEPT_ID", map.get("MDID") == null ? null : map.get("MDID"));
        result.put("BUSINESS_CIRCLE_ID", map.get("SQID") == null ? null : map.get("SQID"));

        result.put("COMPANY_ID", map.get("GSID") == null ? null : map.get("GSID"));
        result.put("OPERATION", map.get("YYMS") == null ? null : map.get("YYMS"));

        return result;
    }

}
